package org.katas.taxi;

import java.math.BigDecimal;

public class Taxi {

    public static final int STARTING_FARE_DISTANCE = 2;
    public static final double STARTING_FARE = 6.00;
    public static final int SHORT_DISTANCE = 8;
    public static final double SHORT_FARE = 0.8;
    public static final double LONG_DISTANCE_RATE = 1.5;
    public static final double WAITING_FARE = 0.25;
    private TaxiPrinter taxiPrinter;

    public Taxi() {
    }

    public Taxi(TaxiPrinter taxiPrinter) {
        this.taxiPrinter = taxiPrinter;
    }

    public BigDecimal meter(int distance) {
        if (distance < 0) {
            throw new IllegalArgumentException("invalid distance: " + distance );
        }
        if (distance <= STARTING_FARE_DISTANCE) {
            return BigDecimal.valueOf(STARTING_FARE);
        }
        if (distance <= SHORT_DISTANCE) {
            return BigDecimal.valueOf(STARTING_FARE + (distance - STARTING_FARE_DISTANCE) * SHORT_FARE);
        }
        return BigDecimal.valueOf(STARTING_FARE + (SHORT_DISTANCE - STARTING_FARE_DISTANCE) * SHORT_FARE +
                (distance - SHORT_DISTANCE) * SHORT_FARE * LONG_DISTANCE_RATE);
    }
    public BigDecimal meter(int distance, int waitTime) {
        if (distance < 0) {
            throw new IllegalArgumentException("invalid distance: " + distance );
        }

        double waitingFare = WAITING_FARE * waitTime;

        if (distance <= STARTING_FARE_DISTANCE) {
            return BigDecimal.valueOf(STARTING_FARE+ waitingFare);
        }
        if (distance <= SHORT_DISTANCE) {
            return BigDecimal.valueOf(STARTING_FARE + (distance - STARTING_FARE_DISTANCE) * SHORT_FARE+ waitingFare);
        }
        return BigDecimal.valueOf(STARTING_FARE + (SHORT_DISTANCE - STARTING_FARE_DISTANCE) * SHORT_FARE +
                (distance - SHORT_DISTANCE) * SHORT_FARE * LONG_DISTANCE_RATE+ waitingFare);
    }


    public void submit(int distance, int waitTime) {
        BigDecimal fare = meter(distance, waitTime);
        if (taxiPrinter != null) {
            taxiPrinter.print(distance, waitTime, fare);
        }
        pay(fare);
    }

    public void pay(BigDecimal fare) {

    }

    public void submit(Invoice invoice) {
        if (taxiPrinter != null) {
            taxiPrinter.print(invoice.asString());
        }
    }
}
